/**
 * LinkedLST
 * May 11, 2011
 * ChecklistView.java - Activity for pre- and post- route checklists
 */
package edu.washington.cs.labspecimentransport;
import java.util.List;

import org.apache.http.conn.ConnectTimeoutException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
import edu.washington.cs.labspecimentransport.adapters.SeparatedListAdapter;
import edu.washington.cs.labspecimentransport.data.DataQuery;
import edu.washington.cs.labspecimentransport.dataobjects.ChecklistItem;
import edu.washington.cs.labspecimentransport.ops.CommonHandlers;
import edu.washington.cs.labspecimentransport.ops.Keys;

/**
 * A ChecklistView displays the checklist of tasks that need to be performed
 * before and after a courier's route.
 * 
 * <p>
 * An intent with the following keys are expected:
 * 	int : KEY_COURIERID - the courier id
 * 
 */
public class ChecklistView extends Activity {
	private List<ChecklistItem> before_checklist;	// the checklist for before tasks
	private List<ChecklistItem> after_checklist;	// the checklist for after tasks
    private Bundle infoBundle;						// information stored in this activity's intent
    private DataQuery dq;							// DataQuery object for backend communication
    
    // flags for completion of before and after checklists
    private boolean beforeDone;
    private boolean afterDone;
    
    // counters for number of checks for each checklist
    private int beforeCheckedCount;
    private int afterCheckedCount;
    
    private boolean firstExecution;					// flag for whether initial setup is required
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.checklist);
        
        firstExecution = true;
        beforeCheckedCount = 0;
        afterCheckedCount = 0;
        
        setupButtons();
        updateChecklist();
    }
    
    /**
     * Define the options menu.
     */
    public boolean onCreateOptionsMenu(Menu menu) {
    	menu.add(0, Keys.MENUID_REFRESH, 0, R.string.option_refresh);
    	menu.add(0, Keys.MENUID_HOME, 0, R.string.option_home);
    	menu.add(0, Keys.MENUID_HELP, 0, R.string.option_help);
    	return true;
    }

    /**
     * Define functionality for each item in options menu.
     */
    public boolean onOptionsItemSelected(MenuItem item) {   
        switch(item.getItemId()) {
        case Keys.MENUID_REFRESH:
        	updateChecklist();
        	break;
        
        case Keys.MENUID_HOME:
        	CommonHandlers.returnHome(this);
        	break;
        	
        case Keys.MENUID_HELP:
        	CommonHandlers.startHelp(this);
        	break;
        	
        default:
        	super.onOptionsItemSelected(item);
        	break;
    }
        
        return true;
    }
      
    /** Finishes this activity and return results back to HomeView. */
    private void saveChecklist() {
    	if (beforeCheckedCount == before_checklist.size()) {
    		beforeDone = true;
    	}
    	if (afterCheckedCount == after_checklist.size()) {
    		afterDone = true;
    	}
    	
    	Intent intent = new Intent(ChecklistView.this, HomeView.class);
        Bundle newBundle = new Bundle();
        newBundle.putAll(getIntent().getExtras());
        newBundle.putBoolean(Keys.KEY_CHECKLIST_BEFORE, beforeDone);
        newBundle.putBoolean(Keys.KEY_CHECKLIST_AFTER, afterDone);
        intent.putExtras(newBundle);
        setResult(Activity.RESULT_OK, intent);
        finish();
    }
    
    /** Extract information from intent. */
    private void getPassedData() {
    	infoBundle = getIntent().getExtras();
    	beforeDone = infoBundle.getBoolean(Keys.KEY_CHECKLIST_BEFORE);
    	afterDone = infoBundle.getBoolean(Keys.KEY_CHECKLIST_AFTER);
    	
    	dq = DataQuery.getInstance(); // create a new query to retrieve a list of items
    }
    
    /** Sets onClick handlers for all buttons. */
    private void setupButtons() {
    	// onClick handler for "Home" button
    	Button h = (Button) findViewById(R.id.home_button);
    	h.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				CommonHandlers.returnHome(ChecklistView.this);
			}
    	}); 
    	
    	// onClick handler for "Refresh" button
    	Button r = (Button) findViewById(R.id.refresh_button);
    	r.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				updateChecklist();
			}
    	});     	
    	
        // onClick event handler for "Done" button
        Button done = (Button) findViewById(R.id.checklist_save);
        done.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
            	saveChecklist();
            }
        });
    }
    
    /** 
     * Refresh the checklists. 
     */
    private void updateChecklist() {
    	new UpdateChecklist().execute();
    }
    
    /** 
     * Displays the before and after checklists. 
     */
    private void displayList() {
    	SeparatedListAdapter adapter = new SeparatedListAdapter(this);
    	adapter.addSection("Before (" + before_checklist.size() + " items)", 
    			new ChecklistAdapter(this, before_checklist, true));
    	adapter.addSection("After (" + after_checklist.size() + " items)", 
    			new ChecklistAdapter(this, after_checklist, false));
    	
        ListView list = (ListView) findViewById(R.id.checklist);
        list.setAdapter(adapter); 
    }
    
    /** Adapter for displaying checklist. */
    private class ChecklistAdapter extends BaseAdapter {

    	private Context context;
    	private List<ChecklistItem> items;
    	private boolean isBeforeChecklist;
    	
    	/**
    	 * Adapter for displaying checklists
    	 * @param context	context of the listview
    	 * @param checklist list of ChecklistItem to display
    	 * @param isBefore	true if the checklist is the "Before" list
    	 */
		public ChecklistAdapter(Context context, List<ChecklistItem> checklist, 
				boolean isBefore) {
			this.context = context;
			this.items = checklist;
			this.isBeforeChecklist = isBefore;
		}

		public int getCount() {
			return items.size();
		}

		public ChecklistItem getItem(int pos) {
			return items.get(pos);
		}

		public long getItemId(int pos) {
			return items.indexOf(this.getItem(pos));
		}
	
		public View getView(int position, View view, ViewGroup parent) {
			ChecklistItem item = this.getItem(position);
			LinearLayout itemLayout = (LinearLayout) 
				LayoutInflater.from(context).inflate(R.layout.checklist_single, parent, false);
			
			// display the name of the checklist item
			TextView taskname = (TextView) itemLayout.findViewById(R.id.checklist_item);
			taskname.setText("" + item.getTask_text());
			
			CheckBox cb = (CheckBox) itemLayout.findViewById(R.id.checklist_box);
			if (isBeforeChecklist) {
				cb.setChecked(beforeDone);
			} else {
				cb.setChecked(afterDone);
			}
			
			// onClick handler for list item
			cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				public void onCheckedChanged(CompoundButton buttonView,
						boolean isChecked) {					
					if (isBeforeChecklist) {
						if (isChecked) {
							beforeCheckedCount++;
						} else {
							beforeCheckedCount--;
						}
					} else {
						if (isChecked) {
							afterCheckedCount++;
						} else {
							afterCheckedCount--;
						}
					}
				}
			});
			
			return itemLayout;
		}
    	
    }
    
    /** Async task for retrieving the before and after checklist from backend. */
    private class UpdateChecklist extends AsyncTask<Void, Void, Void> {
    	private ProgressDialog dialog;
    	private boolean success;
    	private boolean timeout;
    	
		// before execution
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			success = true;
			timeout = false;
			dialog = ProgressDialog.show(ChecklistView.this, "", 
					getString(R.string.checklist_load_updateChecklist), true, true,
					new DialogInterface.OnCancelListener(){
				public void onCancel(DialogInterface dialog) {
					UpdateChecklist.this.cancel(true);
					finish();
				}
			});
		}
		
		// execution
		@Override
		protected Void doInBackground(Void... v) {
			try {
				// if ChecklistView is in initialization, initialize data
				if (firstExecution) {
					getPassedData();
					firstExecution = false;
				}
				before_checklist = dq.getBeforeChecklist();
				after_checklist = dq.getAfterChecklist();
				
				if (beforeDone) {
					beforeCheckedCount = before_checklist.size();
				}
				if (afterDone) {
					afterCheckedCount = after_checklist.size();
				}
				
			} catch (NullPointerException e) {
				success = false;
			} catch (ConnectTimeoutException e) {
				timeout = true;
			}
			return null;
		}

		// after execution
		@Override
		protected void onPostExecute(Void unused) {
			dialog.dismiss();
			if (success) {
				displayList();
			} else if (timeout) {
				Toast toast = Toast.makeText(ChecklistView.this, 
						R.string.error_timeout, Toast.LENGTH_LONG);
				toast.show();
			} else {
				Toast toast = Toast.makeText(ChecklistView.this, 
						R.string.error_default, Toast.LENGTH_LONG);
				toast.show();
			}
		}    	
    }
}
